from abc import ABCMeta, abstractmethod
from typing import Tuple

from torch import Tensor


class Metric(metaclass=ABCMeta):
    """Abstract for any kind of metric.
    """

    def __init__(self, name: str):
        self.name = name
        self.sum_metric = 0
        self.num_inst = 0

    @abstractmethod
    def update(self, pred: Tensor, label: Tensor):
        pass

    def reset(self):
        self.sum_metric = 0
        self.num_inst = 0

    def get(self) -> Tuple[str, float]:
        return self.name, self.sum_metric / self.num_inst
